package cn.com.header.core.support.json.fastjson.codec;

import cn.com.header.core.support.json.fastjson.AbstractCodec;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.serializer.SerializeWriter;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;

/**
 * JSON 本地序列化
 * 支持 LocalDate、LocalDateTime、LocalTime
 *
 * @author liangzhongqiu789@sina.com
 * @date 2017-05-27
 * @time 15:03
 */
public class LocalCodec extends AbstractCodec {

    Method _parse;
    DateTimeFormatter dateTimeFormatter;
    Class<? extends Temporal> clazz;

    public LocalCodec(Class<? extends Temporal> clazz, DateTimeFormatter dateTimeFormatter) {
        this.clazz = clazz;
        this.dateTimeFormatter = dateTimeFormatter;
        try {
            _parse = clazz.getMethod("parse", CharSequence.class, DateTimeFormatter.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public LocalCodec(Class<? extends Temporal> clazz, String pattern) {
        this(clazz, DateTimeFormatter.ofPattern(pattern));
    }

    @Override
    public void doWrite(SerializeWriter out, Object object) throws IOException {
        String text = dateTimeFormatter.format((Temporal) object);
        out.writeString(text);
    }

    @Override
    public <T> T doDeserialze(JSONLexer lexer, Type type, Object fieldName) {
        String text = lexer.stringVal();
        lexer.nextToken();
        try {
            return (T) _parse.invoke(clazz, new Object[]{text, dateTimeFormatter});
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int getFastMatchToken() {
        return JSONToken.LITERAL_STRING;
    }
}
